package com.tbit.main.controller;

import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.OperateLog;
import com.tbit.main.constant.*;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.service.CalibrateService;
import com.tbit.main.service.GeoreGionService;
import com.tbit.main.service.RoleService;
import com.tbit.main.service.TokenService;
import com.tbit.main.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 围栏分区
 *
 * @author LMY
 * @create 2020-11-23 11:06
 */
@RestController
@RequestMapping("/georegion")
public class GeoreGionController {
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private GeoreGionService georeGionService;
    @Autowired
    private RoleService roleService;

    /**
     * 添加
     */
    @RequestMapping("/add")
    @OperateLog(module = ModuleEnum.REGION, methods = MethodEnum.GEOREGION_ADD)
    public JsonResult add(String token, GeoreGion georeGion, Integer mapType) {

        Assert.notNull(georeGion.getPoints(), "Georegion.points.notNull");
        Assert.notNull(georeGion.getAccountId(), "AccountUser.agentId.notNull");
        GeoreGion geoRegionByName = georeGionService.getByGeoRegionName(georeGion.getAccountId(), georeGion.getRegionName());
        if (geoRegionByName != null) {
            throw new BaseException("该运营区内有重复的分区名称");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }

        /** 计算电子围栏中心点 */
        List<Point> points = GeoUtil.getPoints(georeGion.getPoints());
        Point newPoint = GeoUtil.GetCenterPoint(points);
        georeGion.setCenterLat(newPoint.getY());
        georeGion.setCenterLon(newPoint.getX());
        /** 经纬度校准 */
        calibrateService.calGeoreGion(georeGion, mapType, SysConstant.ORIGINAL);

        /**判断是否相交*/
        List<GeoreGion> geoRegions = georeGionService.getByAccountId(georeGion.getAccountId());
        if (geoRegions != null) {
            for (GeoreGion geoRegion : geoRegions) {
                if (PolygonUtil.polygon(georeGion.getPoints(), geoRegion.getPoints())) {
                    throw new BaseException("Georegion.Intersect");
                }
            }
        }

        if (georeGion.getRemark() == null) {
            georeGion.setRemark("");
        }
        georeGion.setUpdateTime(DateTimeUtil.getNowTime());
        georeGionService.insert(georeGion);

        return JsonResult.succ();
    }

    /**
     * 更新
     */
    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.REGION, methods = MethodEnum.MAIN_GEOREGION_UPDATE)
    public JsonResult edit(String token, GeoreGion georeGion, Integer mapType) {
        /* 校验 */
        Assert.notNull(georeGion.getRegionId(), "Georegion.regionId.notNull");
        Assert.notNull(georeGion.getPoints(), "Georegion.points.notNull");
        GeoreGion geoRegionByName = georeGionService.getByGeoRegionName(georeGion.getAccountId(), georeGion.getRegionName());
        if (geoRegionByName != null && !Objects.equals(geoRegionByName.getRegionId(), georeGion.getRegionId())) {
            throw new BaseException("该运营区内有重复的分区名称");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }

        /** 计算电子围栏中心点 */
        List<Point> points = GeoUtil.getPoints(georeGion.getPoints());
        Point newPoint = GeoUtil.GetCenterPoint(points);

        georeGion.setCenterLat(newPoint.getY());
        georeGion.setCenterLon(newPoint.getX());
        /** 保存高德地图原始经纬度 */
        georeGion.setPoints(georeGion.getPoints());
        georeGion.setUpdateTime(DateTimeUtil.getNowTime());

        /** 经纬度校准 */
        calibrateService.calGeoreGion(georeGion, mapType, SysConstant.ORIGINAL);

        /**查询分区点*/
        GeoreGion georeGionDB = georeGionService.getByRegionId(georeGion.getRegionId());

        /**判断是否相交*/
        List<GeoreGion> geoRegions = georeGionService.getByAccountId(georeGionDB.getAccountId());
        if (geoRegions != null) {
            for (GeoreGion geoRegion : geoRegions) {
                if (!geoRegion.getRegionId().equals(georeGion.getRegionId())) {
                    if (PolygonUtil.polygon(georeGion.getPoints(), geoRegion.getPoints())) {
                        throw new BaseException("Georegion.Intersect");
                    }
                }
            }
        }

        /**替换可修改字段*/
        ObjectUtil.assign(georeGion, georeGionDB, null);

        georeGionService.update(georeGion);

        return JsonResult.succ();
    }

    /**
     * 删除
     */
    @RequestMapping("/del")
    @OperateLog(module = ModuleEnum.REGION, methods = MethodEnum.GEOREGION_DEL)
    public JsonResult del(String token, Integer regionId) {
        /* 校验 */
        Assert.notNull(regionId, "Georegion.regionId.notNull");

        georeGionService.delete(regionId);

        return JsonResult.succ();
    }

    /**
     * 根据平台账号id查询
     */
    @RequestMapping("/getByAccountId")
    public JsonResult getByAccountId(String token, Integer mapType, Integer accountId) {
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        List<GeoreGion> georeGions = georeGionService.getByAccountId(accountId);

        /**统计数量*/
        if (georeGions.size() > 0) {
            List<GeoreGionMachineCount> georeGionMachineCounts = georeGionService.groupByGeoreGion(accountId);
            Map<Integer, Integer> ppcMap = new HashMap<Integer, Integer>();
            for (GeoreGionMachineCount ppmc : georeGionMachineCounts) {
                ppcMap.put(ppmc.getRegionId(), ppmc.getMachineCount());
            }

            for (GeoreGion pp : georeGions) {
                Integer machineCount = ppcMap.get(pp.getRegionId());
                if (machineCount != null) {
                    pp.setMachineCount(machineCount);
                } else {
                    pp.setMachineCount(0);
                }
            }

        }
        /** 校准 */
        calibrateService.celibrateGeoreGion(georeGions, MapConstant.MAP_ORI, mapType);

        return JsonResult.succ(georeGions);
    }

    /**
     * 绑定分区
     */
    @RequestMapping("/binding")
    @OperateLog(module = ModuleEnum.REGION, methods = MethodEnum.MAIN_GEOREGION_BINDING)
    public JsonResult binding(String token, GeoreGionBound georeGionBound) {

        Assert.notNull(georeGionBound.getRegionId(), "Georegion.regionId.notNull");
        Assert.notNull(georeGionBound.getAccountUserId(), "Georegion.AccountUserId.notNull");
        Assert.notNull(georeGionBound.getIsLeader(), "Georegion.IsLeader.notNull");
        Assert.notNull(georeGionBound.getAccountId(), "AccountUser.agentId.notNull");

        if (georeGionBound.getIsLeader() == 1) {
            List<GeoreGionBound> georeGionBound1 = georeGionService.getGeoreGionBound(georeGionBound.getRegionId(), null, 1);
            if (georeGionBound1.size() > 0) {
                throw new BaseException("Georegion.AccountUser.exist");
            }
        }

        List<GeoreGionBound> georeGionBoundDB = georeGionService.getGeoreGionBound(georeGionBound.getRegionId(), georeGionBound.getAccountUserId(), null);

        if (georeGionBoundDB.size() > 0) {
            throw new BaseException("Georegion.AccountUser.existGeo");
        } else {
            georeGionBound.setBoundTime(DateTimeUtil.getNowTime());
            if (georeGionBound.getRemark() == null) {
                georeGionBound.setRemark("");
            }

            if (georeGionBound.getIsLeader() == null) {
                georeGionBound.setIsLeader(0);
            }

            georeGionService.binding(georeGionBound);
        }
        return JsonResult.succ();
    }

    /**
     * 解绑分区
     */
    @RequestMapping("/unbind")
    @OperateLog(module = ModuleEnum.REGION, methods = MethodEnum.GEOREGION_UNBIND)
    public JsonResult unbind(String token, GeoreGionBound georeGionBound) {

        Assert.notNull(georeGionBound.getRegionId(), "Georegion.regionId.notNull");
        Assert.notNull(georeGionBound.getAccountUserId(), "Georegion.AccountUserId.notNull");
        Assert.notNull(georeGionBound.getAccountId(), "AccountUser.agentId.notNull");

        georeGionService.unbind(georeGionBound);

        return JsonResult.succ();
    }

    /**
     * 更新分区
     */
    @RequestMapping("/update")
    @OperateLog(module = ModuleEnum.REGION, methods = MethodEnum.GEOREGION_UPDATENEW)
    public JsonResult update(String token, GeoreGionBound georeGionBound) {

        Assert.notNull(georeGionBound.getRegionId(), "Georegion.regionId.notNull");
        Assert.notNull(georeGionBound.getAccountUserId(), "Georegion.AccountUserId.notNull");
        Assert.notNull(georeGionBound.getIsLeader(), "Georegion.IsLeader.notNull");
        Assert.notNull(georeGionBound.getAccountId(), "AccountUser.agentId.notNull");

        if (georeGionBound.getIsLeader() == 1) {
            List<GeoreGionBound> georeGionBound1 = georeGionService.getGeoreGionBound(georeGionBound.getRegionId(), null, 1);
            if (georeGionBound1.size() > 0) {
                georeGionService.updateUnbind(georeGionBound1.get(0).getAccountId(), georeGionBound1.get(0).getRegionId(), georeGionBound1.get(0).getAccountUserId(), 0);
            }
        }
        georeGionService.updateUnbind(georeGionBound.getAccountId(), georeGionBound.getRegionId(), georeGionBound.getAccountUserId(), georeGionBound.getIsLeader());
        return JsonResult.succ();
    }

    /**
     * 查询分区
     */
    @RequestMapping("/query")
    public JsonResult query(String token, GeoreGionBound georeGionBound) {

        Assert.notNull(georeGionBound.getAccountId(), "AccountUser.agentId.notNull");

        List<GeoreGionBound> georeGionBoundList = georeGionService.getGeoreGionBound(georeGionBound.getRegionId(), georeGionBound.getAccountUserId(), null);

        return JsonResult.succ(georeGionBoundList);
    }

    /**
     * 根据平台账号id查询绑定
     */
    @RequestMapping("/getByAccountIdBound")
    public JsonResult getByAccountIdBound(String token, Integer mapType, Integer accountId) {

        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        AccountUser accountUserToken = tokenService.getAccount(token);

        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        List<GeoreGion> georeGions = new LinkedList<>();


        if (roleService.getRoleCode(accountUserToken.getAccountUserType()).equals(1)) {
            georeGions = georeGionService.getAccountUserId(accountUserToken.getAccountUserId());
        } else {
            georeGions = georeGionService.getByAccountId(accountId);
        }

        /**统计数量*/
        if (georeGions.size() > 0) {
            List<GeoreGionMachineCount> georeGionMachineCounts = georeGionService.groupByGeoreGion(accountId);
            Map<Integer, Integer> ppcMap = new HashMap<Integer, Integer>();
            for (GeoreGionMachineCount ppmc : georeGionMachineCounts) {
                ppcMap.put(ppmc.getRegionId(), ppmc.getMachineCount());
            }

            for (GeoreGion pp : georeGions) {
                Integer machineCount = ppcMap.get(pp.getRegionId());
                if (machineCount != null) {
                    pp.setMachineCount(machineCount);
                } else {
                    pp.setMachineCount(0);
                }
            }

        }
        /** 校准 */
        calibrateService.celibrateGeoreGion(georeGions, MapConstant.MAP_ORI, mapType);

        return JsonResult.succ(georeGions);
    }

}